`include "PRV564Config.v"
`include "PRV564Define.v"
/*****************************************************************************************
 *    author  : Jack's Team
 *    engineer: Xingyu PAN Xiaoyu HONG
 *    e-mail  : 
 *    date    : 20210904
 *    desc    : PRV564 Main Pipeline (Kernel)
 *    version : 0010(RV64.Mext is avilible now)
 
Family 	: PRV5
Module 	: 564 Top module
Arch    : Vostok
ISA		: RISC-V 64bit Extension U,S,I,M,A

 __  __                   __           __         
/\ \/\ \                 /\ \__       /\ \        
\ \ \ \ \    ___     ____\ \ ,_\   ___\ \ \/'\    
 \ \ \ \ \  / __`\  /',__\\ \ \/  / __`\ \ , <    
  \ \ \_/ \/\ \L\ \/\__, `\\ \ \_/\ \L\ \ \ \\`\  
   \ `\___/\ \____/\/\____/ \ \__\ \____/\ \_\ \_\
    `\/__/  \/___/  \/___/   \/__/\/___/  \/_/\/_/


    This is a 64bit RISC-V processor

   "I see Earth! It is so beautiful!"
                        —— Yuri Gagarin

**********************************************************************************************/
module PRV564_Kernel
#(
    parameter HARTID = 'h0,
    ITLB_FIBID=8'h04,
    DTLB_FIBID=8'h05
)
(
    input wire                  Kernel_CLKi,
    input wire                  Kernel_ARSTi,
//---------------TLB Access port---------------------------
    output  wire              ITLB_FIBo_WREN,        //write to FIB1 enable
    output  wire              ITLB_FIBo_REQ,         //request FIB1 trans
    input   wire              ITLB_FIBi_ACK,         //request acknowledge
    input   wire              ITLB_FIBi_FULL,        //FIB1 FIFO full
    output  wire [7:0]        ITLB_FIBo_ID,
    output  wire [7:0]        ITLB_FIBo_CMD,
    output  wire [3:0]        ITLB_FIBo_BURST,
    output  wire [3:0]        ITLB_FIBo_SIZE,
    output  wire [`XLEN-1:0]  ITLB_FIBo_ADDR,      
    output  wire [`XLEN-1:0]  ITLB_FIBo_DATA,
    input   wire [7:0]        ITLB_FIBi_ID,
    input   wire [7:0]        ITLB_FIBi_RPL,
    input   wire              ITLB_FIBi_V,
    input   wire [`XLEN-1:0]  ITLB_FIBi_DATA,
    //---------------FIB0-----------------
    output  wire              DTLB_FIBo_WREN,        //write to FIB0 enable
    output  wire              DTLB_FIBo_REQ,         //request FIB0 trans
    input   wire              DTLB_FIBi_ACK,         //request acknowledge
    input   wire              DTLB_FIBi_FULL,        //FIB0 FIFO full
    output  wire [7:0]        DTLB_FIBo_ID,
    output  wire [7:0]        DTLB_FIBo_CMD,
    output  wire [3:0]        DTLB_FIBo_BURST,
    output  wire [3:0]        DTLB_FIBo_SIZE,
    output  wire [`XLEN-1:0]  DTLB_FIBo_ADDR,      
    output  wire [`XLEN-1:0]  DTLB_FIBo_DATA,
    input   wire [7:0]        DTLB_FIBi_ID,
    input   wire [7:0]        DTLB_FIBi_RPL,
    input   wire              DTLB_FIBi_V,
    input   wire [`XLEN-1:0]  DTLB_FIBi_DATA,
//----------------To cache port---------------------------
    output wire                 ICache_AQ_V,      DCache_AQ_V,
    output wire [7:0]           ICache_AQ_ID,     DCache_AQ_ID,
    output wire [7:0]           ICache_AQ_CMD,    DCache_AQ_CMD,
    output wire                 ICache_AQ_CI,     DCache_AQ_CI,
    output wire                 ICache_AQ_WT,     DCache_AQ_WT,
    output wire [15:0]          ICache_AQ_BSEL,   DCache_AQ_BSEL,
    output wire [127:0]                           DCache_AQ_WDATA,
    output wire [`XLEN-1:0]     ICache_AQ_ADDR,   DCache_AQ_ADDR,
    input wire                  ICache_AQ_FULL,   DCache_AQ_FULL,
    input wire                  ICache_RQ_V,      DCache_RQ_V,
    input wire [7:0]            ICache_RQ_ID,     DCache_RQ_ID,
    input wire                  ICache_RQ_WRERR,  DCache_RQ_WRERR,
    input wire                  ICache_RQ_RDERR,  DCache_RQ_RDERR,
    input wire                  ICache_RQ_RDY,    DCache_RQ_RDY,
    input wire [127:0]          ICache_RQ_RDATA,  DCache_RQ_RDATA,
    output wire                 ICache_RQ_ACK,    DCache_RQ_ACK,

//---------------Interrupt signal-------------------------
    input wire                  Kernel_MTIi,        //Machine mode timer interrupt
    input wire                  Kernel_MSIi,        //Machine mode software interrupt
    input wire                  Kernel_MEIi,        //Machine mode ext interrupt
    input wire                  Kernel_SEIi,        //Supervisior mode ext interrupt
    input wire                  Kernel_NMIPLi,      //Power lost!
    input wire                  Kernel_NMIEEi,      //Ecc Error
    input wire                  Kernel_NMIGi,       //General purpose
//--------------Machine mode timer-----------------------
    input wire [63:0]           Kernel_MTIMEi	    //Machine mode timer value in
`ifdef DEBUG_FLAG
//RV-Formal & difftest ports
    // ,output reg        rvfi_valid,
	// output reg [63:0] rvfi_order,
	// output reg [31:0] rvfi_insn,
	// output reg        rvfi_trap,
	// output reg        rvfi_halt,
	// output reg        rvfi_intr,
	// output reg [ 1:0] rvfi_mode,
	// output reg [ 1:0] rvfi_ixl,
	// output reg [ 4:0] rvfi_rs1_addr,
	// output reg [ 4:0] rvfi_rs2_addr,
	// output reg [31:0] rvfi_rs1_rdata,
	// output reg [31:0] rvfi_rs2_rdata,
	// output reg [ 4:0] rvfi_rd_addr,
	// output reg [31:0] rvfi_rd_wdata,
	// output reg [31:0] rvfi_pc_rdata,
	// output reg [31:0] rvfi_pc_wdata,
	// output reg [31:0] rvfi_mem_addr,
	// output reg [ 3:0] rvfi_mem_rmask,
	// output reg [ 3:0] rvfi_mem_wmask,
	// output reg [31:0] rvfi_mem_rdata,
	// output reg [31:0] rvfi_mem_wdata,
    // Let alone CSR first
	// output reg [63:0] rvfi_csr_mcycle_rmask,
	// output reg [63:0] rvfi_csr_mcycle_wmask,
	// output reg [63:0] rvfi_csr_mcycle_rdata,
	// output reg [63:0] rvfi_csr_mcycle_wdata,

	// output reg [63:0] rvfi_csr_minstret_rmask,
	// output reg [63:0] rvfi_csr_minstret_wmask,
	// output reg [63:0] rvfi_csr_minstret_rdata,
	// output reg [63:0] rvfi_csr_minstret_wdata,
`endif
);
    wire                Global_Flush,   Branch_Flush;       //全局刷新, 分支刷新
    wire [`XLEN-1:0]    Global_newPC,   Branch_newPC;       //全局刷新用的PC值, 分支刷新使用的PC
    wire                Global_fence,   Global_fencei,  Global_fencevma;
    //--------------BTB---------------------
    wire                BTB_wren,   BTB_wr_predicatebit;
    wire [`XLEN-1:0]    BTB_wrPC,   BTB_wr_predicatePC;
    //---------------CSR---------------------
    wire                CSR_tsr,    CSR_tvm,    CSR_sum,    CSR_mpriv,  CSR_mxr;
    wire [1:0]          CSR_priv,   CSR_mpp;
	wire                CSR_mige,   CSR_sige;              // M模式、S模式中断全局开 (Global enable)
    wire [`XLEN-1:0]    CSR_mideleg,CSR_medeleg,CSR_mie,    CSR_mip;
    wire [43:0]         CSR_satpppn;
    wire [3:0]          CSR_satpmode;
    wire                CSR_en;
    wire [11:0]         CSR_index;
    wire [`XLEN-1:0]    CSR_data;
    wire                CSR_InhibitDcache, CSR_InhibitIcache, CSR_DCacheWT;
    //----------------Regfile---------------
    //wire              RS1_en,     RS2_en;                 //regfile is always enable, not use
    wire [4:0]          RS1_index,  RS2_index;
    wire [`XLEN-1:0]    RS1_data,   RS2_data;               //data output from GPR
    reg  [`XLEN-1:0]    Read_DS1,   Read_DS2;               //data read by IDU
    //---------------Instruction Front to IDU---------------
    wire                PIP_IDUi_MSC_valid,     PIP_IDUi_MSC_InstAccFlt,    PIP_IDUi_MSC_InstAddrMis,   PIP_IDUi_MSC_InstPageFlt;
    wire [`XLEN-1:0]    PIP_IDUi_DATA_instr,    PIP_IDUi_INFO_pc,   PIP_IDUi_INFO_predictedPC;
    wire [1:0]          PIP_IDUi_INFO_priv;
    wire                PIP_IFi_FC_ready,       IFi_ModifyPermit;
    //---------------IDU to ALU-------------------
    wire                PIP_ALUi_MSC_valid;
    wire [7:0]          PIP_ALUi_Opcode;
    wire [1:0]          PIP_ALUi_OpInfo;
    wire [`XLEN-1:0]    PIP_ALUi_DATA_ds1;
    wire [`XLEN-1:0]    PIP_ALUi_DATA_ds2;
    wire [`XLEN-1:0]    PIP_ALUi_INFO_pc;
    wire [1:0]          PIP_ALUi_INFO_priv;
    wire [7:0]          PIP_ALUi_INFO_itag;
    wire                PIP_ALUo_FC_ready;
    //---------------ALU to write back------------
    wire           		PIP_ALUo_MSC_valid;
    wire [`XLEN-1:0]    PIP_ALUo_DATA_data1;
    wire [`XLEN-1:0]    PIP_ALUo_DATA_data2;
    wire [`XLEN-1:0]    PIP_ALUo_INFO_pc;
    wire [1:0]          PIP_ALUo_INFO_priv;
    wire [7:0]          PIP_ALUo_INFO_itag;
    wire                PIP_ALUi_FC_ready;
    //---------------IDU to Mcop------------------
    wire                PIP_Mcopi_MSC_valid;
    wire [1:0]          PIP_Mcopi_OPInfo;
    wire [7:0]          PIP_Mcopi_Opcode;
    wire [`XLEN-1:0]    PIP_Mcopi_DATA_ds1;
    wire [`XLEN-1:0]    PIP_Mcopi_DATA_ds2;
    wire [`XLEN-1:0]    PIP_Mcopi_INFO_pc;
    wire [1:0]          PIP_Mcopi_INFO_priv;
    wire [7:0]          PIP_Mcopi_INFO_ITAG;
    wire                PIP_Mcopo_FC_ready;
    //--------------Mcop to commit---------------
    wire           		PIP_Mcopo_MSC_valid;
    wire [`XLEN-1:0]    PIP_Mcopo_DATA_data1;
    wire [`XLEN-1:0]    PIP_Mcopo_INFO_pc;
    wire [1:0]          PIP_Mcopo_INFO_priv;
    wire [7:0]          PIP_Mcopo_INFO_itag;
    wire                PIP_Mcopi_FC_ready;
    //---------------IDU to LSU-------------------
    wire                PIP_LSUi_MSC_valid;
    wire [7:0]          PIP_LSUi_Opcode;
    wire [3:0]          PIP_LSUi_OpSize;
    wire [1:0]          PIP_LSUi_OpInfo;
    wire [`XLEN-1:0]    PIP_LSUi_DATA_ds1;
    wire [`XLEN-1:0]    PIP_LSUi_DATA_ds2;
    wire                PIP_LSUi_INFO_unpage;
    wire [`XLEN-1:0]    PIP_LSUi_INFO_pc;
    wire [1:0]          PIP_LSUi_INFO_priv;
    wire [7:0]          PIP_LSUi_INFO_itag;
    wire                PIP_LSUo_FC_ready;
    //---------------LSU to write back------------
    wire           		PIP_LSUo_MSC_valid;
    wire           		PIP_LSUo_MSC_LoadPageFlt ;
    wire           		PIP_LSUo_MSC_LoadAccFlt  ;
    wire           		PIP_LSUo_MSC_LoadAddrMis ;
    wire           		PIP_LSUo_MSC_StorePageFlt;
    wire           		PIP_LSUo_MSC_StoreAccFlt ;
    wire           		PIP_LSUo_MSC_StoreAddrMis;
    wire [`XLEN-1:0]    PIP_LSUo_DATA_data1;
    wire [`XLEN-1:0]    PIP_LSUo_DATA_data2;
    wire                PIP_LSUo_INFO_ci;
    wire [`XLEN-1:0]    PIP_LSUo_INFO_pc;
    wire [1:0]          PIP_LSUo_INFO_priv;
    wire [7:0]          PIP_LSUo_INFO_itag;
    wire                PIP_LSUi_FC_ready;
    //---------------------commit-----------------------
    wire                CMT_valid;
    wire                CMT_GPRwen;                         //write back enable
    wire [`XLEN-1:0]    CMT_pc,    CMT_data1,  CMT_data2;   //write back data
    wire [4:0]          CMT_GPRwindex;
    wire [11:0]         CMT_csrindex;
    wire                CMT_csren;
    wire [1:0]          CMT_priv;
    wire                CMT_ci;
    wire [`XLEN-1:0]    CMT_trap_value, CMT_trap_cause, CMT_trap_pc;
    wire                CMT_trap_s,     CMT_trap_m,     CMT_trap_async;
    wire                CMT_mret,       CMT_sret;
    wire                CMT_system;

//-----------------------------------DITF--------------------------------------
//------------dependencies Check port---------------
    wire            DITFi_Checken;          //check enable
    wire [4:0]      DITFi_CheckRs1Index;    //rs1 index for check
    wire            DITFi_CheckRs1en;       //rs1 index for check is enable
    wire [4:0]      DITFi_CheckRs2Index;    //rs2 index for check
    wire            DITFi_CheckRs2en;       //rs2 index for check is enable
    wire [11:0]     DITFi_CheckCSRIndex;    //csr index for check
    wire            DITFi_CheckCSRen;       //csr index for check is enable
    wire            DITFo_DepdcFind;        //A dependencies is found
//---------------Write Port Signal------------------
    wire            DITFi_write,        DITFi_remove;           //Write enable (add a new entry)
    wire            DITFo_write_ready;                          //write is ready
    wire [7:0]      DITFi_itag,         DITFo_itag;             //instruction's tag
    wire [4:0]      DITFi_rs1index;
    wire            DITFi_rs1en;
    wire [4:0]      DITFi_rs2index;
    wire            DITFi_rs2en;
    wire [4:0]      DITFi_rdindex,      DITFo_rdindex;
    wire            DITFi_rden,         DITFo_rden;
    wire [11:0]     DITFi_csrindex,     DITFo_csrindex;
    wire            DITFi_csren,        DITFo_csren;
    wire            DITFi_jmp,          DITFo_jmp;              //This is a jump/Branch instruction
    wire            DITFi_InsAccessFlt, DITFo_InsAccessFlt;
    wire            DITFi_InsPageFlt,   DITFo_InsPageFlt;
    wire            DITFi_InsAddrMis,   DITFo_InsAddrMis;
    wire            DITFi_illins,       DITFo_illins;           //illigal instruction
    wire            DITFi_mret,         DITFo_mret;             //Machine mode return
    wire            DITFi_sret,         DITFo_sret;             //Supervisior mode return
    wire            DITFi_ecall,        DITFo_ecall;            //environment call
    wire            DITFi_fence,        DITFo_fence;
    wire            DITFi_fencei,       DITFo_fencei;
    wire            DITFi_fencevma,     DITFo_fencevma;
    wire            DITFi_ebreak,       DITFo_ebreak;           //environment break
    wire            DITFi_system,       DITFo_system;           //this is a system-type instruction
    wire                                DITFo_v;

`ifdef DEBUG_FLAG
    reg [63:0] InstrPC;
    reg [63:0] exceptionPC;
    reg [63:0] intrNO;
    reg [63:0] cause;
    //output [31:0]InstrCommit;
    wire [(32*`XLEN)-1:0]IntRegState;
    reg CommitValid;
    reg        skip;
    reg        isRVC;
    reg        scFailed;
    reg        wen;
    reg [ 7:0] wdest;
    reg [63:0] wdata;

    //CSR wire for difftest
    wire [ 1:0] priviledgeMode;
    wire [63:0] mstatus;
    wire [63:0] sstatus;
    wire [63:0] mepc;
    wire [63:0] sepc;
    wire [63:0] mtval;
    wire [63:0] stval;
    wire [63:0] mtvec;
    wire [63:0] stvec;
    wire [63:0] mcause;
    wire [63:0] scause;
    wire [63:0] satp;
    wire [63:0] mip;
    wire [63:0] mie;
    wire [63:0] mscratch;
    wire [63:0] sscratch;
    wire [63:0] mideleg;
    wire [63:0] medeleg;
    // 对CSR的值延一拍，以确保difftest不会抽风 操
    reg [ 1:0] r_priviledgeMode;
    reg [63:0] r_mstatus;
    reg [63:0] r_sstatus;
    reg [63:0] r_mepc;
    reg [63:0] r_sepc;
    reg [63:0] r_mtval;
    reg [63:0] r_stval;
    reg [63:0] r_mtvec;
    reg [63:0] r_stvec;
    reg [63:0] r_mcause;
    reg [63:0] r_scause;
    reg [63:0] r_satp;
    reg [63:0] r_mip;
    reg [63:0] r_mie;
    reg [63:0] r_mscratch;
    reg [63:0] r_sscratch;
    reg [63:0] r_mideleg;
    reg [63:0] r_medeleg;
    //ArchEvent 

    //TrapEvent 
    wire [63:0] trap_pc;
    wire trap_valid;
    wire [7:0]trap_code;
    wire [63:0] cycleCnt;
    wire [63:0] instrCnt;
`endif
//-----------------------------------Instruction Front--------------------------------------
InstrFront #(.ITLB_FIBID(ITLB_FIBID)) InstrFront(
    .IFi_CLK                      (Kernel_CLKi),
    .IFi_ARST                     (Kernel_ARSTi),
    .IFi_GFlush                   (Global_Flush),
    .IFi_GPC                      (Global_newPC),
    .IFi_BFlush                   (Branch_Flush),
    .IFi_BPC                      (Branch_newPC),
    .IFi_fencei                   (Global_fencei),
    .IFi_fencevma                 (Global_fencevma),
    //--------------BTB port-------------------
    .BTB_wr_req                   (BTB_wren),
    .BTB_wr_PC                    (BTB_wrPC),
    .BTB_wr_predicted_PC          (BTB_wr_predicatePC),
    .BTB_wr_predicted_state_bit   (BTB_wr_predicatebit),
    //--------------CSR value in----------------
    .CSR_satpppn                  (CSR_satpppn),
    .CSR_satpmode                 (CSR_satpmode),
    .CSR_priv                     (CSR_priv),
    .CSR_mxr                      (CSR_mxr),
    .CSR_sum                      (CSR_sum),
    .CSR_InhibitIcache            (CSR_InhibitIcache),
    //-----------To next stage-------------------
    .PIP_IFo_MSC_valid            (PIP_IDUi_MSC_valid),
    .PIP_IFo_DATA_instr           (PIP_IDUi_DATA_instr),
    .PIP_IFo_INFO_pc              (PIP_IDUi_INFO_pc),
    .PIP_IFo_INFO_predictedPC     (PIP_IDUi_INFO_predictedPC),
    .PIP_IFo_INFO_priv            (PIP_IDUi_INFO_priv),
    .PIP_IFo_MSC_InstPageFlt      (PIP_IDUi_MSC_InstPageFlt),
    .PIP_IFo_MSC_InstAccFle       (PIP_IDUi_MSC_InstAccFlt),
    .PIP_IFo_MSC_InstAddrMis      (PIP_IDUi_MSC_InstAddrMis),
    .PIP_IFi_FC_ready             (PIP_IFi_FC_ready),
    //-----------------ITLB_FIB--------------------------
    .ITLB_FIBo_WREN                (ITLB_FIBo_WREN),
    .ITLB_FIBo_REQ                 (ITLB_FIBo_REQ),
    .ITLB_FIBi_ACK                 (ITLB_FIBi_ACK),
    .ITLB_FIBi_FULL                (ITLB_FIBi_FULL),
    .ITLB_FIBo_ID                  (ITLB_FIBo_ID),
    .ITLB_FIBo_CMD                 (ITLB_FIBo_CMD),
    .ITLB_FIBo_BURST               (ITLB_FIBo_BURST),
    .ITLB_FIBo_SIZE                (ITLB_FIBo_SIZE),
    .ITLB_FIBo_ADDR                (ITLB_FIBo_ADDR),
    .ITLB_FIBo_DATA                (ITLB_FIBo_DATA),
    .ITLB_FIBi_ID                  (ITLB_FIBi_ID),
    .ITLB_FIBi_RPL                 (ITLB_FIBi_RPL),
    .ITLB_FIBi_V                   (ITLB_FIBi_V),
    .ITLB_FIBi_DATA                (ITLB_FIBi_DATA),
    //--------------------ICache Interface---------------------------
    .IFo_AQ_V                      (ICache_AQ_V),
    .IFo_AQ_ID                     (ICache_AQ_ID),
    .IFo_AQ_CMD                    (ICache_AQ_CMD),
    .IFo_AQ_CI                     (ICache_AQ_CI),
    .IFo_AQ_WT                     (ICache_AQ_WT),
    .IFo_AQ_BSEL                   (ICache_AQ_BSEL),
    .IFo_AQ_WDATA                  (),                        //instruction front don't need write data
    .IFo_AQ_ADDR                   (ICache_AQ_ADDR),
    .IFi_AQ_FULL                   (ICache_AQ_FULL),
    .IFi_RQ_V                      (ICache_RQ_V),
    .IFi_RQ_ID                     (ICache_RQ_ID),
    .IFi_RQ_WRERR                  (ICache_RQ_WRERR),
    .IFi_RQ_RDERR                  (ICache_RQ_RDERR),
    .IFi_RQ_RDY                    (ICache_RQ_RDY),
    .IFi_RQ_RDATA                  (ICache_RQ_RDATA),
    .IFo_RQ_ACK                    (ICache_RQ_ACK)
);

//------------------------------------Instruction Decode Unit--------------------------------
IDU                             IDU(
    .IDUi_CLK                      (Kernel_CLKi),
    .IDUi_ARST                     (Kernel_ARSTi),
    //----------------Global Flush-----------
    .IDUi_Flush                    (Global_Flush),
    //-------------Read CSR and GPR----------
    .IDUi_CSR_tvm                  (CSR_tvm),
    .IDUi_CSR_tsr                  (CSR_tsr),
    .IDUi_CSR_mpriv                (CSR_mpriv),
    .IDUi_CSR_mpp                  (CSR_mpp),
    .IDUi_CSR_data                 (CSR_data),
    .IDUo_CSR_index                (CSR_index),
    .IDUo_CSR_en                   (CSR_en),
    .IDUo_GPR_rs1index             (RS1_index),
    .IDUo_GPR_rs1en                (),                  //regfile always read enable
    .IDUi_GPR_rs1data              (Read_DS1),
    .IDUo_GPR_rs2index             (RS2_index),
    .IDUo_GPR_rs2en                (),
    .IDUi_GPR_rs2data              (Read_DS2),
    //--------Data Depdence Check port---------
    .IDUo_Checken                  (DITFi_Checken),
    .IDUo_CheckRs1en               (DITFi_CheckRs1en),
    .IDUo_CheckRs1Index            (DITFi_CheckRs1Index),
    .IDUo_CheckRs2en               (DITFi_CheckRs2en),
    .IDUo_CheckRs2Index            (DITFi_CheckRs2Index),
    .IDUo_CheckCSRIndex            (DITFi_CheckCSRIndex),
    .IDUo_CheckCSRen               (DITFi_CheckCSRen),
    .IDUi_DepdcFind                (DITFo_DepdcFind),
    //--------------DITF write port--------------
    .IDUo_DITF_write               (DITFi_write),
    .IDUo_DITF_itag                (DITFi_itag),
    .IDUo_DITF_rs1index            (DITFi_rs1index),
    .IDUo_DITF_rs1en               (DITFi_rs1en),
    .IDUo_DITF_rs2index            (DITFi_rs2index),
    .IDUo_DITF_rs2en               (DITFi_rs2en),
    .IDUo_DITF_rdindex             (DITFi_rdindex),
    .IDUo_DITF_rden                (DITFi_rden),
    .IDUo_DITF_csrindex            (DITFi_csrindex),
    .IDUo_DITF_csren               (DITFi_csren),
    .IDUo_DITF_jmp                 (DITFi_jmp),
    .IDUo_DITF_InsAccessFlt        (DITFi_InsAccessFlt),
    .IDUo_DITF_InsPageFlt          (DITFi_InsPageFlt),
    .IDUo_DITF_InsAddrMis          (DITFi_InsAddrMis),
    .IDUo_DITF_illins              (DITFi_illins),
    .IDUo_DITF_mret                (DITFi_mret),
    .IDUo_DITF_sret                (DITFi_sret),
    .IDUo_DITF_ecall               (DITFi_ecall),
    .IDUo_DITF_ebreak              (DITFi_ebreak),
    .IDUo_DITF_fence               (DITFi_fence),
    .IDUo_DITF_fencei              (DITFi_fencei),
    .IDUo_DITF_fencevma            (DITFi_fencevma),
    .IDUo_DITF_system              (DITFi_system),
    .IDUi_DITF_write_ready         (DITFo_write_ready),     //if v=0, there is no entry in DITF
    //----------Branch Flush------------
    .IDUo_BFlush                   (Branch_Flush),
    .IDUo_BPC                      (Branch_newPC),
    //----------BTB port----------------
    .IDUo_BTB_wrPC                 (BTB_wrPC),
    .IDUo_BTB_wren                 (BTB_wren),
    .IDUo_BTB_wr_predicatebit      (BTB_wr_predicatebit),
    .IDUo_BTB_wr_predicatePC       (BTB_wr_predicatePC),
    //---------IDU pipline input--------
    .PIP_IDUi_MSC_valid            (PIP_IDUi_MSC_valid),
    .PIP_IDUi_DATA_instr           (PIP_IDUi_DATA_instr),
    .PIP_IDUi_INFO_pc              (PIP_IDUi_INFO_pc),
    .PIP_IDUi_INFO_predictedPC     (PIP_IDUi_INFO_predictedPC),
    .PIP_IDUi_INFO_priv            (PIP_IDUi_INFO_priv),
    .PIP_IDUi_MSC_InstPageFlt      (PIP_IDUi_MSC_InstPageFlt),
    .PIP_IDUi_MSC_InstAddrMis      (PIP_IDUi_MSC_InstAddrMis),
    .PIP_IDUi_MSC_InstAccFlt       (PIP_IDUi_MSC_InstAccFlt),
    .PIP_IDUo_FC_ready             (PIP_IFi_FC_ready),
    //--------Dispatch to ALU-----------
    .PIP_ALUi_MSC_valid            (PIP_ALUi_MSC_valid),
    .PIP_ALUi_INFO_pc              (PIP_ALUi_INFO_pc),
    .PIP_ALUi_INFO_priv            (PIP_ALUi_INFO_priv),
    .PIP_ALUi_INFO_ITAG            (PIP_ALUi_INFO_itag),
    .PIP_ALUi_Opcode               (PIP_ALUi_Opcode),
    .PIP_ALUi_OpSize               (),                  //ALU don't need opsize, ALU just need opcode and opinfo
    .PIP_ALUi_OPInfo               (PIP_ALUi_OpInfo),
    .PIP_ALUi_DATA_ds1             (PIP_ALUi_DATA_ds1),
    .PIP_ALUi_DATA_ds2             (PIP_ALUi_DATA_ds2),
    .PIP_ALUo_FC_ready             (PIP_ALUo_FC_ready),
    //---------Dispatch to LSU------------
    .PIP_LSUi_MSC_valid            (PIP_LSUi_MSC_valid),
    .PIP_LSUi_INFO_pc              (PIP_LSUi_INFO_pc),
    .PIP_LSUi_INFO_priv            (PIP_LSUi_INFO_priv),
    .PIP_LSUi_INFO_ITAG            (PIP_LSUi_INFO_itag),
    .PIP_LSUi_INFO_unpage          (PIP_LSUi_INFO_unpage),
    .PIP_LSUi_Opcode               (PIP_LSUi_Opcode),
    .PIP_LSUi_OpSize               (PIP_LSUi_OpSize),
    .PIP_LSUi_OPInfo               (PIP_LSUi_OpInfo),
    .PIP_LSUi_DATA_ds1             (PIP_LSUi_DATA_ds1),
    .PIP_LSUi_DATA_ds2             (PIP_LSUi_DATA_ds2),
    .PIP_LSUo_FC_ready             (PIP_LSUo_FC_ready),
    //---------Dispatch to Math coprocssor------
    .PIP_Mcopi_MSC_valid           (PIP_Mcopi_MSC_valid),
    .PIP_Mcopi_INFO_pc             (PIP_Mcopi_INFO_pc),
    .PIP_Mcopi_INFO_priv           (PIP_Mcopi_INFO_priv),
    .PIP_Mcopi_INFO_ITAG           (PIP_Mcopi_INFO_ITAG),
    .PIP_Mcopi_Opcode              (PIP_Mcopi_Opcode),
    .PIP_Mcopi_OpSize              (),                          //ALU don't need opsize, ALU just need opcode and opinfo
    .PIP_Mcopi_OPInfo              (PIP_Mcopi_OPInfo),
    .PIP_Mcopi_DATA_ds1            (PIP_Mcopi_DATA_ds1),
    .PIP_Mcopi_DATA_ds2            (PIP_Mcopi_DATA_ds2),
    .PIP_Mcopo_FC_ready            (PIP_Mcopo_FC_ready)
    //Dispatch to Float Coprocessor

    //Dispatch to SIMD_Vector Coprocessor

);
//---------------------------------read regfile bypass-----------------------
always@(*)begin
    if(RS1_index == 5'b0)begin
        Read_DS1 = 64'h0;
    end
    else if(CMT_GPRwen & (CMT_GPRwindex == RS1_index))begin     //if read index == commit index, bypass enable
        Read_DS1 = CMT_data1;
    end
    else begin
        Read_DS1 = RS1_data;
    end

    if(RS2_index == 5'b0)begin
        Read_DS2 = 64'h0;
    end
    else if(CMT_GPRwen & (CMT_GPRwindex == RS2_index))begin
        Read_DS2 = CMT_data1;
    end
    else begin
        Read_DS2 = RS2_data;
    end
end
//------------------------------------Regfile--------------------------------
RegFile       Regfile(
	.clk                    (Kernel_CLKi),
	.wr_en                  (CMT_GPRwen),
	.rd0_addr               (CMT_GPRwindex),
	.rs1_addr               (RS1_index),
	.rs2_addr               (RS2_index),
	.rd0_data               (CMT_data1),
	.rs1_data               (RS1_data),
	.rs2_data               (RS2_data)
    `ifdef DEBUG_FLAG
        ,.snapshot              (IntRegState)     
    `endif
) ;
//---------------------------Dispatch Instruction FIFO (DITF)----------------
DITF                    DITF0(
    .DITFi_CLK                (Kernel_CLKi),
    .DITFi_ARST               (Kernel_ARSTi),
    .DITFi_SRST               (Global_Flush),
    //-----------Data Dependence check-------------(Data dependence check now mov to scoreboard)
    .DITFi_Checken            (DITFi_Checken),
    .DITFi_CheckRs1Index      (DITFi_CheckRs1Index),
    .DITFi_CheckRs1en         (DITFi_CheckRs1en),
    .DITFi_CheckRs2Index      (DITFi_CheckRs2Index),
    .DITFi_CheckRs2en         (DITFi_CheckRs2en),
    .DITFi_CheckCSRIndex      (DITFi_CheckCSRIndex),
    .DITFi_CheckCSRen         (DITFi_CheckCSRen),
    .DITFo_DepdcFind          (DITFo_DepdcFind),
    //----------DITF write port---------------------
    .DITFo_write_ready        (DITFo_write_ready),
    .DITFi_write              (DITFi_write),
    .DITFi_itag               (DITFi_itag),
    .DITFi_rs1index           (DITFi_rs1index),
    .DITFi_rs1en              (DITFi_rs1en),
    .DITFi_rs2index           (DITFi_rs2index),
    .DITFi_rs2en              (DITFi_rs2en),
    .DITFi_rdindex            (DITFi_rdindex),
    .DITFi_rden               (DITFi_rden),
    .DITFi_csrindex           (DITFi_csrindex),
    .DITFi_csren              (DITFi_csren),
    .DITFi_jmp                (DITFi_jmp),
    .DITFi_InsAccessFlt       (DITFi_InsAccessFlt),
    .DITFi_InsPageFlt         (DITFi_InsPageFlt),
    .DITFi_InsAddrMis         (DITFi_InsAddrMis),
    .DITFi_illins             (DITFi_illins),
    .DITFi_mret               (DITFi_mret),
    .DITFi_sret               (DITFi_sret),
    .DITFi_ecall              (DITFi_ecall),
    .DITFi_ebreak             (DITFi_ebreak),
    .DITFi_fence              (DITFi_fence),
    .DITFi_fencei             (DITFi_fencei),
    .DITFi_fencevma           (DITFi_fencevma),
    .DITFi_system             (DITFi_system),
    .DITFi_remove             (DITFi_remove),
    //---------------DITF read port---------------
    .DITFo_v                  (DITFo_v),
    .DITFo_itag               (DITFo_itag),
    .DITFo_rs1index           (),
    .DITFo_rs1en              (),
    .DITFo_rs2index           (),
    .DITFo_rs2en              (),
    .DITFo_rdindex            (DITFo_rdindex),
    .DITFo_rden               (DITFo_rden),
    .DITFo_csrindex           (DITFo_csrindex),
    .DITFo_csren              (DITFo_csren),
    .DITFo_jmp                (DITFo_jmp),
    .DITFo_InsAccessFlt       (DITFo_InsAccessFlt),
    .DITFo_InsPageFlt         (DITFo_InsPageFlt),
    .DITFo_InsAddrMis         (DITFo_InsAddrMis),
    .DITFo_illins             (DITFo_illins),
    .DITFo_mret               (DITFo_mret),
    .DITFo_sret               (DITFo_sret),
    .DITFo_ecall              (DITFo_ecall),
    .DITFo_ebreak             (DITFo_ebreak),
    .DITFo_fence              (DITFo_fence),
    .DITFo_fencei             (DITFo_fencei),
    .DITFo_fencevma           (DITFo_fencevma),
    .DITFo_system             (DITFo_system)
);
//-----------------------------ALU-------------------------------------------
ALU                     ALU(
    .ALUi_CLK                 (Kernel_CLKi),
    .ALUi_ARST                (Kernel_ARSTi),
    .ALUi_Flush               (Global_Flush),
    //-------------ALU input from IDU---------------
    .PIP_ALUi_MSC_valid       (PIP_ALUi_MSC_valid),
    .PIP_ALUi_Opcode          (PIP_ALUi_Opcode),
    .PIP_ALUi_OpInfo          (PIP_ALUi_OpInfo),
    .PIP_ALUi_INFO_itag       (PIP_ALUi_INFO_itag),
    .PIP_ALUi_INFO_priv       (PIP_ALUi_INFO_priv),
    .PIP_ALUi_INFO_PC         (PIP_ALUi_INFO_pc),
    .PIP_ALUi_DATA_ds1        (PIP_ALUi_DATA_ds1),
    .PIP_ALUi_DATA_ds2        (PIP_ALUi_DATA_ds2),
    .PIP_ALUo_FC_ready        (PIP_ALUo_FC_ready),
    //-------------ALU output to writeback----------
    .PIP_ALUo_MSC_valid       (PIP_ALUo_MSC_valid),
    .PIP_ALUo_INFO_itag       (PIP_ALUo_INFO_itag),
    .PIP_ALUo_INFO_pc         (PIP_ALUo_INFO_pc),
    .PIP_ALUo_INFO_priv       (PIP_ALUo_INFO_priv),
    .PIP_ALUo_DATA_data1      (PIP_ALUo_DATA_data1),
    .PIP_ALUo_DATA_data2      (PIP_ALUo_DATA_data2),
    .PIP_ALUi_FC_ready        (PIP_ALUi_FC_ready)
);
//------------------------Math-coprocessor (Long int popline)------------------------------
md_wrapper              Mcop(
// Global signals
    .clk                      (Kernel_CLKi),
    .arst                     (Kernel_ARSTi),
    .flush                    (Global_Flush),
// Input handshake
    .i_valid                  (PIP_Mcopi_MSC_valid),
    .i_opcode                 (PIP_Mcopi_Opcode),
    .i_opinfo                 (PIP_Mcopi_OPInfo),
    .i_data1                  (PIP_Mcopi_DATA_ds1),
    .i_data2                  (PIP_Mcopi_DATA_ds2),
    .i_tag                    (PIP_Mcopi_INFO_ITAG),
    .i_priv                   (PIP_Mcopi_INFO_priv),
    .i_pc                     (PIP_Mcopi_INFO_pc),
    .i_ready                  (PIP_Mcopo_FC_ready),
// Output handshake
    .d_result                 (PIP_Mcopo_DATA_data1),
    .d_valid                  (PIP_Mcopo_MSC_valid),
    .d_tag                    (PIP_Mcopo_INFO_itag),
    .d_priv                   (PIP_Mcopo_INFO_priv),
    .d_pc                     (PIP_Mcopo_INFO_pc),
    .d_ready                  (PIP_Mcopi_FC_ready)
);
//-------------------------------LSU---------------------------------
LSU #(.DTLB_FIBID(DTLB_FIBID)) LSU
(
    .LSUi_CLK                     (Kernel_CLKi),
    .LSUi_ARST                    (Kernel_ARSTi),
    .LSUi_ModifyPermit            (DITFo_v),
    .LSUi_ModifyPermitID          (DITFo_itag),
    .LSUi_Flush                   (Global_Flush),
    .LSUi_fence                   (Global_fence),
    .LSUi_fencevma                (Global_fencevma),
    .CSR_satpppn                  (CSR_satpppn),
    .CSR_satpmode                 (CSR_satpmode),
    .CSR_priv                     (CSR_priv),
    .CSR_mxr                      (CSR_mxr),
    .CSR_sum                      (CSR_sum),
    .CSR_InhibitDcache            (CSR_InhibitDcache),
    .CSR_DCacheWT                 (CSR_DCacheWT),
    .PIP_LSUi_MSC_valid           (PIP_LSUi_MSC_valid),         //操作有效
    .PIP_LSUi_Opcode              (PIP_LSUi_Opcode),            //LSU操作码
    .PIP_LSUi_OpInfo              (PIP_LSUi_OpInfo),            //LSU操作信息
    .PIP_LSUi_OpSize              (PIP_LSUi_OpSize), 
    .PIP_LSUi_INFO_itag           (PIP_LSUi_INFO_itag),
    .PIP_LSUi_INFO_priv           (PIP_LSUi_INFO_priv),         //权限
    .PIP_LSUi_INFO_pc             (PIP_LSUi_INFO_pc),           //Instruction Infomation: PC value
    .PIP_LSUi_INFO_unpage         (PIP_LSUi_INFO_unpage),
    .PIP_LSUi_DATA_ds1            (PIP_LSUi_DATA_ds1),
    .PIP_LSUi_DATA_ds2            (PIP_LSUi_DATA_ds2),
    .PIP_LSUo_FC_ready            (PIP_LSUo_FC_ready),
//--------------------Pipline Output Signals----------------
    .PIP_LSUo_MSC_valid           (PIP_LSUo_MSC_valid),
    .PIP_LSUo_MSC_LoadPageFlt     (PIP_LSUo_MSC_LoadPageFlt),
    .PIP_LSUo_MSC_LoadAccFlt      (PIP_LSUo_MSC_LoadAccFlt),
    .PIP_LSUo_MSC_LoadAddrMis     (PIP_LSUo_MSC_LoadAddrMis),
    .PIP_LSUo_MSC_StorePageFlt    (PIP_LSUo_MSC_StorePageFlt),
    .PIP_LSUo_MSC_StoreAccFlt     (PIP_LSUo_MSC_StoreAccFlt),
    .PIP_LSUo_MSC_StoreAddrMis    (PIP_LSUo_MSC_StoreAddrMis),
    .PIP_LSUo_INFO_ci             (PIP_LSUo_INFO_ci),
    .PIP_LSUo_INFO_itag           (PIP_LSUo_INFO_itag),
    .PIP_LSUo_INFO_pc             (PIP_LSUo_INFO_pc),
    .PIP_LSUo_INFO_priv           (PIP_LSUo_INFO_priv),
    .PIP_LSUo_DATA_data1          (PIP_LSUo_DATA_data1),        //data1 output(), for GPR write back
    .PIP_LSUo_DATA_data2          (PIP_LSUo_DATA_data2),
    .PIP_LSUi_FC_ready            (PIP_LSUi_FC_ready),
//--------------------FIB1--------------------------
    .DTLB_FIBo_WREN               (DTLB_FIBo_WREN),        //write to FIB0 enable
    .DTLB_FIBo_REQ                (DTLB_FIBo_REQ),         //request FIB0 trans
    .DTLB_FIBi_ACK                (DTLB_FIBi_ACK),         //request acknowledge
    .DTLB_FIBi_FULL               (DTLB_FIBi_FULL),        //FIB0 FIFO full
    .DTLB_FIBo_ID                 (DTLB_FIBo_ID),
    .DTLB_FIBo_CMD                (DTLB_FIBo_CMD),
    .DTLB_FIBo_BURST              (DTLB_FIBo_BURST),
    .DTLB_FIBo_SIZE               (DTLB_FIBo_SIZE),
    .DTLB_FIBo_ADDR               (DTLB_FIBo_ADDR),      
    .DTLB_FIBo_DATA               (DTLB_FIBo_DATA),
    .DTLB_FIBi_ID                 (DTLB_FIBi_ID),
    .DTLB_FIBi_RPL                (DTLB_FIBi_RPL),
    .DTLB_FIBi_V                  (DTLB_FIBi_V),
    .DTLB_FIBi_DATA               (DTLB_FIBi_DATA),
//------------------------Cache port--------------------
    .LSUo_AQ_V                    (DCache_AQ_V),
    .LSUo_AQ_ID                   (DCache_AQ_ID),
    .LSUo_AQ_CMD                  (DCache_AQ_CMD),
    .LSUo_AQ_CI                   (DCache_AQ_CI),
    .LSUo_AQ_WT                   (DCache_AQ_WT),
    .LSUo_AQ_BSEL                 (DCache_AQ_BSEL),
    .LSUo_AQ_WDATA                (DCache_AQ_WDATA),
    .LSUo_AQ_ADDR                 (DCache_AQ_ADDR),
    .LSUi_AQ_FULL                 (DCache_AQ_FULL),
    .LSUi_RQ_V                    (DCache_RQ_V),
    .LSUi_RQ_ID                   (DCache_RQ_ID),
    .LSUi_RQ_WRERR                (DCache_RQ_WRERR),
    .LSUi_RQ_RDERR                (DCache_RQ_RDERR),
    .LSUi_RQ_RDY                  (DCache_RQ_RDY),
    .LSUi_RQ_RDATA                (DCache_RQ_RDATA),
    .LSUo_RQ_ACK                  (DCache_RQ_ACK)
);

//---------------------------Commit-------------------------
commit                  commit(
    .Global_CLK                  (Kernel_CLKi),
    .Global_ARST                 (Kernel_ARSTi),
    .Global_Flush                (Global_Flush),
    //-----------Trap manage use---------------
    .CSR_mideleg                 (CSR_mideleg),
    .CSR_medeleg                 (CSR_medeleg),
    .CSR_mige                    (CSR_mige),
    .CSR_sige                    (CSR_sige),
    .CSR_mip                     (CSR_mip),
    .CSR_mie                     (CSR_mie),
    .NMI_EccErr                  (Kernel_NMIEEi),
    .NMI_PwrLost                 (Kernel_NMIPLi),
    .NMI_generic                 (Kernel_NMIGi),
    //-------------pipline--------------
    .PIP0i_MSC_valid             (PIP_ALUo_MSC_valid),
    .PIP0i_MSC_LoadPageFlt       (1'b0),
    .PIP0i_MSC_LoadAccFlt        (1'b0),
    .PIP0i_MSC_LoadAddrMis       (1'b0),
    .PIP0i_MSC_StorePageFlt      (1'b0),
    .PIP0i_MSC_StoreAccFlt       (1'b0),
    .PIP0i_MSC_StoreAddrMis      (1'b0),
    .PIP0i_INFO_ci               (1'b0),
    .PIP0i_INFO_itag             (PIP_ALUo_INFO_itag),
    .PIP0i_INFO_pc               (PIP_ALUo_INFO_pc),
    .PIP0i_INFO_priv             (PIP_ALUo_INFO_priv),
    .PIP0i_DATA_data1            (PIP_ALUo_DATA_data1),
    .PIP0i_DATA_data2            (PIP_ALUo_DATA_data2),
    .PIP0o_FC_ready              (PIP_ALUi_FC_ready),
    //-----------pipline 1---------------
    .PIP1i_MSC_valid             (PIP_LSUo_MSC_valid),
    .PIP1i_MSC_LoadPageFlt       (PIP_LSUo_MSC_LoadPageFlt),
    .PIP1i_MSC_LoadAccFlt        (PIP_LSUo_MSC_LoadAccFlt),
    .PIP1i_MSC_LoadAddrMis       (PIP_LSUo_MSC_LoadAddrMis),
    .PIP1i_MSC_StorePageFlt      (PIP_LSUo_MSC_StorePageFlt),
    .PIP1i_MSC_StoreAccFlt       (PIP_LSUo_MSC_StoreAccFlt),
    .PIP1i_MSC_StoreAddrMis      (PIP_LSUo_MSC_StoreAddrMis),
    .PIP1i_INFO_ci               (PIP_LSUo_INFO_ci),
    .PIP1i_INFO_itag             (PIP_LSUo_INFO_itag),
    .PIP1i_INFO_pc               (PIP_LSUo_INFO_pc),
    .PIP1i_INFO_priv             (PIP_LSUo_INFO_priv),
    .PIP1i_DATA_data1            (PIP_LSUo_DATA_data1),
    .PIP1i_DATA_data2            (PIP_LSUo_DATA_data2),
    .PIP1o_FC_ready              (PIP_LSUi_FC_ready),
    //-------------pipline 2-----------------
    .PIP2i_MSC_valid             (PIP_Mcopo_MSC_valid),
    .PIP2i_MSC_LoadPageFlt       (1'b0),
    .PIP2i_MSC_LoadAccFlt        (1'b0),
    .PIP2i_MSC_LoadAddrMis       (1'b0),
    .PIP2i_MSC_StorePageFlt      (1'b0),
    .PIP2i_MSC_StoreAccFlt       (1'b0),
    .PIP2i_MSC_StoreAddrMis      (1'b0),
    .PIP2i_INFO_ci               (1'b0),
    .PIP2i_INFO_itag             (PIP_Mcopo_INFO_itag),
    .PIP2i_INFO_pc               (PIP_Mcopo_INFO_pc),
    .PIP2i_INFO_priv             (PIP_Mcopo_INFO_priv),
    .PIP2i_DATA_data1            (PIP_Mcopo_DATA_data1),
    .PIP2i_DATA_data2            (64'h0),                        //Source2 not use
    .PIP2o_FC_ready              (PIP_Mcopi_FC_ready),
    //--------------DITF port-----------------
    .DITFo_v                     (DITFo_v),
    .DITFo_itag                  (DITFo_itag),
    .DITFo_rdindex               (DITFo_rdindex),
    .DITFo_rden                  (DITFo_rden),
    .DITFo_csrindex              (DITFo_csrindex),
    .DITFo_csren                 (DITFo_csren),
    .DITFo_jmp                   (DITFo_jmp),
    .DITFo_InsAccessFlt          (DITFo_InsAccessFlt),
    .DITFo_InsPageFlt            (DITFo_InsPageFlt),
    .DITFo_InsAddrMis            (DITFo_InsAddrMis),
    .DITFo_illins                (DITFo_illins),
    .DITFo_mret                  (DITFo_mret),
    .DITFo_sret                  (DITFo_sret),
    .DITFo_ecall                 (DITFo_ecall),
    .DITFo_ebreak                (DITFo_ebreak),
    .DITFo_fence                 (DITFo_fence),
    .DITFo_fencei                (DITFo_fencei),
    .DITFo_fencevma              (DITFo_fencevma),
    .DITFo_system                (DITFo_system),
    .DITFi_remove                (DITFi_remove),
    //---------------commit port------------------
    .CMT_valid                   (CMT_valid),
    .CMT_GPRwen                  (CMT_GPRwen),
    .CMT_GPRwindex               (CMT_GPRwindex),
    .CMT_data1                   (CMT_data1),
    .CMT_data2                   (CMT_data2),
    .CMT_csren                   (CMT_csren),
    .CMT_csrindex                (CMT_csrindex),
    .CMT_pc                      (CMT_pc),

`ifdef DEBUG_FLAG

	.CMT_priv                    (CMT_priv),                    //if debug is on(difftest is on), privilege commit will enable
    .CMT_ci                      (CMT_ci),                      //if debug is on(difftest is on), cache inhibit(MMIO) commit will enable, this will cause skip in MMIO instruction

`endif
    //----------target mode and exception code-----
    .CMT_trap_value              (CMT_trap_value), 
    .CMT_trap_cause              (CMT_trap_cause),
    .CMT_trap_pc                 (CMT_trap_pc),
    .CMT_trap_s                  (CMT_trap_s),
    .CMT_trap_m                  (CMT_trap_m),
    .CMT_trap_async              (CMT_trap_async),
    .CMT_mret                    (CMT_mret),
    .CMT_sret                    (CMT_sret),
    .CMT_fence                   (Global_fence),
    .CMT_fencei                  (Global_fencei),
    .CMT_fencevma                (Global_fencevma),
    .CMT_system                  (CMT_system)
);

//-------------------------------write back to csr-----------------------------
//          Finally! the last module 
CSR_top
    #(.HARTID                   (HARTID))
CSR_top(
    .CLKi                       (Kernel_CLKi), 
    .ARSTi                      (Kernel_ARSTi),
    //-------------signals and value from platform--------------
    .mtime                      (Kernel_MTIMEi),                                          //Machine mode time in
    .Interrupt_MEI              (Kernel_MEIi), 
    .Interrupt_MSI              (Kernel_MSIi), 
    .Interrupt_MTI              (Kernel_MTIi),    //Interrupt from platfrom controller
    .Interrupt_SEI              (Kernel_SEIi),
    //---------------pipiline flush and new PC-------------------
    .Global_Flush               (Global_Flush),
    .Global_newPC               (Global_newPC),
    //--------------------read csr port-------------------------
    .csr_rden                   (CSR_en),
    .csr_rdindex                (CSR_index),
    .csr_rddata                 (CSR_data),
    .csr_tsr                    (CSR_tsr),
    .csr_tvm                    (CSR_tvm),
    .csr_sum                    (CSR_sum),
    .csr_mpriv                  (CSR_mpriv),
    .csr_mxr                    (CSR_mxr),
    .csr_priv                   (CSR_priv),
    .csr_mpp                    (CSR_mpp),
    .csr_mige                   (CSR_mige),
    .csr_sige                   (CSR_sige),
    .csr_mideleg                (CSR_mideleg),
    .csr_medeleg                (CSR_medeleg),
    .csr_mip                    (CSR_mip),
    .csr_mie                    (CSR_mie),
    .csr_satpppn                (CSR_satpppn),
    .csr_satpmode               (CSR_satpmode),
    .csr_InhibitIcache          (CSR_InhibitIcache),
    .csr_InhibitDcache          (CSR_InhibitDcache),
    .csr_DCacheWT               (CSR_DCacheWT),
    //---------------Write back information-----------------------
    //---------------commit information-----------------------
    .CMT_valid                   (CMT_valid),
    .CMT_data2                   (CMT_data2),
    .CMT_csren                   (CMT_csren),
    .CMT_csrindex                (CMT_csrindex),
    .CMT_pc                      (CMT_pc),
    .CMT_mret                    (CMT_mret),
    .CMT_sret                    (CMT_sret),
	.CMT_system                  (CMT_system),
    .CMT_trap_value              (CMT_trap_value), 
    .CMT_trap_cause              (CMT_trap_cause),
    .CMT_trap_pc                 (CMT_trap_pc),
    .CMT_trap_s                  (CMT_trap_s),
    .CMT_trap_m                  (CMT_trap_m),
    .CMT_trap_async              (CMT_trap_async)
    
`ifdef DEBUG_FLAG
    ,
    .privilege                 (priviledgeMode),
    .mstatus                    (mstatus),
    .sstatus                    (sstatus),
    .mepc                       (mepc),
    .sepc                       (sepc),
    .mtval                      (mtval),
    .stval                      (stval),
    .mtvec                      (mtvec),
    .stvec                      (stvec),
    .mcause                     (mcause),
    .scause                     (scause),
    .satp                       (satp),
    .mip                        (mip),
    .mie                        (mie),
    .mscratch                   (mscratch),
    .sscratch                   (sscratch),
    .mideleg                    (mideleg),
    .medeleg                    (medeleg),
    //output       trap_valid,
    //output[ 2:0] trap_code,
    //output[63:0] trap_pc,
    .mcycle                     (cycleCnt),
    .minstret                   (instrCnt)
`endif
);
`ifdef DEBUG_FLAG
    reg [63:0] r_intrNO;
    reg [63:0] r_exceptionPC;
    reg        r_async;
    assign trap_valid   = CMT_csren & (CMT_csrindex==`urw_halt_index);
    assign trap_pc      = PIP_IDUi_INFO_pc;
    assign trap_code    = IntRegState[647:640];

    always @(posedge Kernel_CLKi) //THIS IS THE DIFFTEST COMMIT BLOCK
    begin
        InstrPC     <=CMT_pc;
        wen         <=CMT_GPRwen;//TODO COMPLETE THIS SHIT
        wdest       <=CMT_GPRwindex;
        wdata       <=CMT_data1;
        /********************************************************
        非常草生的东西来了：
        Arch Event送进去的东西必须要延1拍
        *********************************************************/

        if(CMT_trap_async)begin                     //当前Arch Event为异步异常：中断,需要延一拍
            r_intrNO    <= CMT_trap_cause;
            r_exceptionPC<= CMT_trap_pc;
            r_async     <= 1'b1;
        end
        else begin
            r_async     <= 1'b0;
            r_intrNO    <= 64'h0;
        end
        r_priviledgeMode    <= priviledgeMode;
        r_mstatus           <= mstatus;
        r_sstatus           <= sstatus;
        r_mepc              <= mepc;
        r_sepc              <= sepc;
        r_mtval             <= mtval;
        r_stval             <= stval;
        r_mtvec             <= mtvec;
        r_stvec             <= stvec;
        r_mcause            <= mcause;
        r_scause            <= scause;
        r_satp              <= satp;
        r_mip               <= mip;
        r_mie               <= mie;
        r_mscratch          <= mscratch;
        r_sscratch          <= sscratch;
        r_mideleg           <= mideleg;
        r_medeleg           <= medeleg;

        intrNO      <= r_intrNO;
        exceptionPC <= r_exceptionPC;
        CommitValid <= CMT_valid;
        //TrapEvent<=1'b0;
        skip        <=(CMT_csren & ((CMT_csrindex==`urw_print_index))) | CMT_ci;
        isRVC       <=1'b0;
        scFailed    <=1'b0;
        if(CMT_csren & (CMT_csrindex==`urw_print_index))begin
            $write("%C",CMT_data2);
        end
    end
`endif
//----------------Debug information output-----------------
`ifdef STUCK_AUTO_STOP
reg [`XLEN-1:0] dummy_cycle_cnt;
always@(posedge Kernel_CLKi)begin
    if(CMT_valid & `DEBUG_RUN)begin
        $display("Kernel RUN: CMT PC=%h, priv=%h, CMT data=%h, wen=%h, CMT dest=%h",CMT_pc, CMT_priv, CMT_data1, CMT_GPRwen, CMT_GPRwindex);
    end
    else begin
        if(dummy_cycle_cnt>5000)begin
            $display("Kernel ERROR: No instr commit in 5000 cycle, stop Simulation");
            $finish;
            $display("mstatus:%h, sstatus:%h, mepc:%h, sepc:%h", mstatus, sstatus, mepc, sepc);
            $display("mtval:%h, stval:%h, mtvec:%h, stvec:%h", mtval, stval, mtvec, stvec);
            $display("mcause:%h, scause:%h, satp:%h",mcause, scause, satp);
            $display("mip:%h, mie:%h, mscratch:%h, sscratch:%h", mip, mie, mscratch, sscratch);
            $display("mideleg:%h, medeleg:%h, mcycle:%h, minstret:%h", mideleg, medeleg, cycleCnt, instrCnt);
        end
    end
    if(CMT_valid)begin
        if(CMT_trap_m)begin
            $display("Kernel INFO: Trap target mode is M, Async=%h, cause=%h, epc=%h",CMT_trap_async, CMT_trap_cause, CMT_trap_pc);
        end
        else if(CMT_trap_s)begin
            $display("Kernel INFO: Trap target mode is S, Async=%h, cause=%h, epc=%h",CMT_trap_async, CMT_trap_cause, CMT_trap_pc);
        end
    end

    if(CMT_valid)begin
        dummy_cycle_cnt <= 0;
    end
    else begin
        dummy_cycle_cnt <= dummy_cycle_cnt + 1;
    end
end
`endif
`ifdef DEBUG_FLAG
//-----------------Kernel Difftest Debug Information-------------------
    wire [63:0]IntReg[31:0];
    genvar i;
    generate for(i=0;i<32;i=i+1) 
    begin : IntRegGen

        assign IntReg[i]=IntRegState[(64*(i+1))-1:64*i];
    end
    endgenerate
    
DifftestInstrCommit Instr_Commit
(
    .clock                  (Kernel_CLKi),
    .coreid                 (8'h00),
    .index                  (8'h00),
    .valid                  (CommitValid),
    .pc                     (InstrPC),
    .instr                  (InstrCommit),
    .skip                   (skip),
    .isRVC                  (isRVC),
    .scFailed               (scFailed),
    .wen                    (wen),
    .wdest                  (wdest),
    .wdata                  (wdata)
);
DifftestArchIntRegState IntRegCommit(
    .clock(Kernel_CLKi),
    .coreid(8'h00),
    .gpr_0(IntReg[0]),
    .gpr_1(IntReg[1]),
    .gpr_2(IntReg[2]),
    .gpr_3(IntReg[3]),
    .gpr_4(IntReg[4]),
    .gpr_5(IntReg[5]),
    .gpr_6(IntReg[6]),
    .gpr_7(IntReg[7]),
    .gpr_8(IntReg[8]),
    .gpr_9(IntReg[9]),
    .gpr_10(IntReg[10]),
    .gpr_11(IntReg[11]),
    .gpr_12(IntReg[12]),
    .gpr_13(IntReg[13]),
    .gpr_14(IntReg[14]),
    .gpr_15(IntReg[15]),
    .gpr_16(IntReg[16]),
    .gpr_17(IntReg[17]),
    .gpr_18(IntReg[18]),
    .gpr_19(IntReg[19]),
    .gpr_20(IntReg[20]),
    .gpr_21(IntReg[21]),
    .gpr_22(IntReg[22]),
    .gpr_23(IntReg[23]),
    .gpr_24(IntReg[24]),
    .gpr_25(IntReg[25]),
    .gpr_26(IntReg[26]),
    .gpr_27(IntReg[27]),
    .gpr_28(IntReg[28]),
    .gpr_29(IntReg[29]),
    .gpr_30(IntReg[30]),
    .gpr_31(IntReg[31])
);

DifftestCSRState CSRCommit(
    .clock                  (Kernel_CLKi),
    .coreid                 (8'h00),
    .priviledgeMode         (r_async ? r_priviledgeMode : priviledgeMode),
    .mstatus                (r_async ? r_mstatus : mstatus),
    .sstatus                (r_async ? r_sstatus : sstatus),
    .mepc                   (r_async ? r_mepc : mepc),
    .sepc                   (r_async ? r_sepc : sepc),
    .mtval                  (r_async ? r_mtval : mtval),
    .stval                  (r_async ? r_stval : stval),
    .mtvec                  (r_async ? r_mtvec : mtvec),
    .stvec                  (r_async ? r_stvec : stvec),
    .mcause                 (r_async ? r_mcause : mcause),
    .scause                 (r_async ? r_scause : scause),
    .satp                   (r_async ? r_satp : satp),
    .mip                    (64'h0),                //不接mip，因为煞笔difftest不知道mip的情况
    .mie                    (r_async ? r_mie : mie),
    .mscratch               (r_async ? r_mscratch : mscratch),
    .sscratch               (r_async ? r_sscratch : sscratch),
    .mideleg                (r_async ? r_mideleg : mideleg),
    .medeleg                (r_async ? r_medeleg : medeleg)
);
DifftestArchEvent ArchEventCommit(
    .clock                  (Kernel_CLKi),
    .coreid                 (8'h00),
    .intrNO                 (intrNO),               //由异步异常产生的错误号，非0触发
    .cause                  (cause),                //由同步异常产生的错误号，非0触发
    .exceptionPC            (exceptionPC)
);
DifftestTrapEvent TrapEventCommit(
    .clock(Kernel_CLKi),
    .coreid(8'h00),
    .valid(trap_valid),
    .code(trap_code),
    .pc(trap_pc),
    .cycleCnt(cycleCnt),
    .instrCnt(instrCnt)
);
wire [63:0] InstrBuf;
assign InstrBuf=ram_read_helper(1'b1, InstrPC);
assign InstrCommit=(InstrPC[3])?InstrBuf[63:32]:InstrBuf[31:0];
`endif

endmodule

